
package redeS.mensagem;

/**
 * Classe que representa uma mensagem gerérica da rede Gnutella.
 * Por ser abstrata não pode ser instanciada, seve apenas de superclasse para outras mensagens
 * Gnutella. Essa classe possui apenas o cabeçalho da mensagem, que é comum a todas.
 * @author thiago-pc
 */
public abstract class GnutellaMessage {
	
	private long descriptorID;
	// payloadDescritor é o tipo da classe (a verificação desse campo é feita com instanceof)
	private int TTL;
	private int hops;
	// payloadLenght não é relevante numa simulação
	
	/**
	 * Construtor de uma mensagem Gnutella genérica. Tem apenas os dados relevantes do
	 * cabeçalho.
	 * @param descriptorID Identificador único da mensagem na rede. Geralmente é gerado
	 * randomicamente.
	 * @param TTL Time-to-leave. Número de vezes que a mensagem será encaminhada antes de
	 * ser excluída da rede. Toda vez que essa mensagem for encaminhada o TTL será
	 * decrementado.
	 */
	public GnutellaMessage(long descriptorID, int TTL){
		this.descriptorID = descriptorID;
		this.TTL = TTL;
		hops = 0;
	}

	/**
	 * Retorna o dentificador único da mensagem na rede.
	 * @return long descriptorID
	 */
	public long getDescriptorID() {
		return descriptorID;
	}

	/**
	 * Retorna o número de vezes que a mensagem ainda pode ser encaminhada.
	 * @return int TTL
	 */
	public int getTTL() {
		return TTL;
	}

	/**
	 * Retorna o número de vezes que a mensagem foi encaminhada.
	 * @return int hops
	 */
	public int getHops() {
		return hops;
	}
	
	/**
	 * Realiza o decremento do TTL atual simultaneamente ao incremento do hops atual.
	 * Esse método deve ser chamado pela classe de controle do simulador toda vez que
	 * essa mensagem for encaminhada.
	 * @return true se foi possível decrementar o TTL, false se o TTL já chegou a zero
	 */
	public boolean TTLDecrement(){
		if(TTL>0){
			TTL--;
			hops++;
			return true;
		}
		else return false;
	}
	
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof GnutellaMessage){
			return descriptorID == ((GnutellaMessage)obj).descriptorID;
		}
		return false;
	}
	
}
